LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY sram_mgr IS
	PORT (
		--THESE PORTS SHOULD BE PORTMAPPED TO PHYSICAL PINS
		clk_50		: IN STD_LOGIC;
		mem_ptr		: IN STD_LOGIC_VECTOR(8 DOWNTO 0);
		ram_mark_i	: IN STD_LOGIC;	
		wr_req		: IN STD_LOGIC;
		rd_req		: IN STD_LOGIC;
		test_en_n	: IN STD_LOGIC;
		
		--
		mem_busy	: OUT STD_LOGIC := '0';
		ram_ptr		: OUT STD_LOGIC_VECTOR(8 DOWNTO 0) := "000000000";
		ram_wr_en	: OUT STD_LOGIC := '0';
		ram_mark_o	: OUT STD_LOGIC := '0';
		wr_req_n	: OUT STD_LOGIC := '1';
		rd_req_n	: OUT STD_LOGIC := '1';
		k_addr_fact	: OUT STD_LOGIC_VECTOR(9 DOWNTO 0) := "1100000000"
	);
END sram_mgr;

ARCHITECTURE Behavior OF sram_mgr IS
	TYPE State_type IS (IDLE, PAUSE, READ, WRITE, TEST);
	--TYPE test_data_array IS ARRAY(7 DOWNTO 0) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
	--TYPE test_addr_array IS ARRAY(7 DOWNTO 0) OF STD_LOGIC_VECTOR(17 DOWNTO 0);
	SIGNAL y : State_type := IDLE;
	SIGNAL pause_cntr : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0011";
	SIGNAL ram_addr : STD_LOGIC_VECTOR(8 DOWNTO 0) := (OTHERS => '0');
	SIGNAL next_slot : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
	SIGNAL incr_slot : STD_LOGIC := '0';
	SIGNAL mark_input : STD_LOGIC := '0';
	--SIGNAL next_ram_addr : STD_LOGIC_VECTOR(8 DOWNTO 0) := ("000000001");
	--SIGNAL ram_switch : STD_LOGIC := '0';
	--SIGNAL test_data : test_data_array;
	--SIGNAL test_addr : test_addr_array;
	--SIGNAL test_index : INTEGER RANGE 0 TO 8;
	--SIGNAL test_delay : STD_LOGIC_VECTOR(25 DOWNTO 0);
	--SIGNAL test_en_n : STD_LOGIC;
BEGIN
	--k_addr_fact <= "1011111001"; --note: 1011111001 = 761d
	
	--define static test codes
--	test_data(0) <= X"0001";
--	test_data(1) <= X"0005";
--	test_data(2) <= X"000F";
--	test_data(3) <= X"00F0";
--	test_data(4) <= X"0F00";
--	test_data(5) <= X"F000";
--	test_data(6) <= X"8000";
--	test_data(7) <= X"AAAA";
--	test_addr(0) <= "00" & X"02F9"; --761d * 1d
--	test_addr(1) <= "00" & X"05F2"; --761d * 2d
--	test_addr(2) <= "00" & X"08EB"; --761d * 3d
--	test_addr(3) <= "00" & X"0BE4"; --761d * 4d
--	test_addr(4) <= "00" & X"0EDD"; --761d * 5d
--	test_addr(5) <= "00" & X"11D6"; --761d * 6d
--	test_addr(6) <= "00" & X"17C8"; --761d * 8d
--	test_addr(7) <= "00" & X"1DBA"; --761d * 10d
	
	PROCESS (clk_50)
	BEGIN
		IF (clk_50'EVENT AND clk_50='1') THEN
			IF (y = IDLE) THEN
				--IDLE
				IF (next_slot /= "000") THEN
					next_slot <= next_slot - 1;
				ELSE
					IF (incr_slot = '1') THEN
						incr_slot <= '0';
						--ram_addr <= (ram_addr + 1);
						ram_ptr <= ram_addr;
						mem_busy <= '0';
					END IF;
				END IF;
				ram_wr_en <= '0';
				wr_req_n <= '1';
				rd_req_n <= '1';
				ram_mark_o <= '0';
				mark_input <= ram_mark_i;
				
				--IF (incr_slot = '0') THEN
					IF (rd_req = '1') THEN
						mem_busy <= '1';
						ram_ptr <= mem_ptr;
						y <= READ;
					ELSIF (wr_req = '1') THEN
						mem_busy <= '1';
						ram_ptr <= ram_addr;
						y <= WRITE;
					END IF;
				--END IF;
			ELSIF (y = PAUSE) THEN
				--wait for one clock cycle
				IF (pause_cntr /= "0000") THEN
					pause_cntr <= pause_cntr - 1;
				ELSE
					pause_cntr <= "0110";
					ram_addr <= (ram_addr + 1);
					ram_ptr <= ram_addr;
					mark_input <= ram_mark_i;
					y <= WRITE;
				END IF;
			ELSIF (y = READ) THEN
				--mark ram as free
				ram_mark_o <= '0';
				ram_wr_en <= '1';
				--enable SRAM read
				rd_req_n <= '0';
				y <= IDLE;
				--y <= PAUSE;
			ELSIF (y = WRITE) THEN
				--if ram location is free...
				IF (mark_input = '0') THEN
					ram_mark_o <= '1';
					ram_wr_en <= '1';
					--enable SRAM write
					wr_req_n <= '0';
					next_slot <= "000";
					incr_slot <= '1';
					ram_addr <= (ram_addr + 1);
					ram_ptr <= ram_addr;
					mark_input <= ram_mark_i;
					y <= IDLE;
					--y <= PAUSE;
				ELSE --ram_mark_i = '1'
					--find a free ram location
					pause_cntr <= "0110";
					y <= PAUSE;
				END IF;
			ELSIF (y = TEST) THEN
				
			END IF;
		END IF;
	END PROCESS;
END Behavior;